﻿#pragma execution_character_set("utf-8")
#include "fileoperator.h"

FileOperator::FileOperator(QObject *parent)
    : QObject{parent}
{

}
bool FileOperator::createDir_if(const QString path){
    QFile file(path);
    return createDir_if(file);
}

bool FileOperator::createDir_if(QFile &file){//查看文件的父级目录是否存在，如果不存在那么创建父级目录
    QString directoryPath = QFileInfo(file).path();
    QDir dir;
    if (!dir.exists(directoryPath)) {  //目录不存在
        return dir.mkpath(directoryPath);
    }
    return true;
}

QByteArray FileOperator::readFile(const QString path){
    QFile file(path);
    return readFile(file);
}

QByteArray FileOperator::readFile(QFile &file){
    if (file.open(QIODevice::ReadOnly)) {
        QByteArray fileContent = file.readAll();
        if (file.error() != QFile::NoError) {
            qDebug() << "Error reading from file:" << file;
            fileContent.clear();
        }
        file.close();
        return fileContent;
    }
    else{
        qDebug() << "Could not open file for binary reading:" << file;
        return QByteArray();
    }
}

bool FileOperator::writeFile(const QString path,const QByteArray &data){
    QFile file(path);
    return writeFile(file,data);
}

bool FileOperator::writeFile(QFile &file,const QByteArray &data){
    if (!createDir_if(file)) {
        qDebug() << "无法创建目录:" << file;
        return false;
    }

    if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
        QDataStream out(&file);
        out.writeRawData(data.constData(), data.size());
        if (!file.flush()) {
            qDebug() << "Could not write to file:" << file;
            file.close();
            return false;
        }
        file.close();
        return true;
    }
    else{
        qDebug() << "无法打开文件以进行写入:" << file.errorString();
        return false;
    }
}
bool  FileOperator::copyFile(const QString &sourcePath,const QString &targetPath){
    QFile sourceFile(sourcePath);
    QFile targetFile(targetPath);
    return copyFile(sourceFile,targetFile);
}

bool FileOperator::copyFile(QFile &sourceFile,QFile &targetFile){
    if (!sourceFile.open(QIODevice::ReadOnly)) {
        qDebug() << "无法打开源文件进行读取:" << sourceFile.errorString();
        return false;
    }

    if (!createDir_if(targetFile)) {
        qDebug() << "无法创建目录:" << targetFile.fileName();
        sourceFile.close();
        return false;
    }

    if (!targetFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
        qDebug() << "无法打开目标文件进行写入:" << targetFile.errorString();
        sourceFile.close();
        return false;
    }

    char buffer[4096]; // 定义一个缓冲区，大小可以根据需要进行调整
    qint64 bytesRead;
    while ((bytesRead = sourceFile.read(buffer, sizeof(buffer))) > 0) {
        if (targetFile.write(buffer, bytesRead) != bytesRead) {
            qDebug() << "写入目标文件时出错:" << targetFile.errorString();
            sourceFile.close();
            targetFile.close();
            return false;
        }
    }

    if (sourceFile.error() != QFile::NoError) {
        qDebug() << "从源文件读取时出错:" << sourceFile.errorString();
        sourceFile.close();
        targetFile.close();
        return false;
    }

    sourceFile.close();
    targetFile.close();
    return true;
}

bool FileOperator::createFile(const QString path){
    QFile file(path);
    return createFile(file);
}
bool FileOperator::createFile(QFile &file){
    if (file.exists()) {//检查文件是否存在
        return true;
    }
    if (!createDir_if(file)) {
        qDebug() << "无法创建目录:" << file;
        return false;
    }
    if (!file.open(QIODevice::WriteOnly)) {
        // 如果文件打开失败，打印错误消息
        qDebug() << "Error opening file:" << file.errorString();
        return false;
    }
    file.close();
    // 检查文件是否确实被创建
    if (file.exists()) {
        return true;
    }
    return false;
}

bool FileOperator::deleteDirectoryRecursively(const QString directoryPath,bool isDelRoot) {
    QDir dir(directoryPath);
    if (!dir.exists()) {
        qDebug() << "Directory does not exist:" << directoryPath;
        return true;
    }

    // 遍历目录下的所有文件和子目录
    QFileInfoList fileList = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
    for (const QFileInfo &fileInfo : fileList) {
        if (fileInfo.isDir()) {
            // 如果是目录，递归删除
            if (!deleteDirectoryRecursively(fileInfo.absoluteFilePath(),isDelRoot)) {
                return false;
            }
        } else {
            // 如果是文件，直接删除
            if (!QFile::remove(fileInfo.absoluteFilePath())) {
                qDebug() << "Failed to delete file:" << fileInfo.absoluteFilePath();
                return false;
            }
        }
    }
    if(isDelRoot){// 删除空目录（所有子目录和文件都已被删除）
        dir.rmdir(directoryPath);
    }
    return true;
}

QVariantMap FileOperator::recursiveReadJsonObject(const QJsonObject &jsonObject) {//读取一个json文档将所有的内容转换成QMap<QString, QVariant>
    QVariantMap resultMap;
    for (auto it = jsonObject.constBegin(); it != jsonObject.constEnd(); ++it)//遍历一个对象中所有内容
    {
        const QString key = it.key();
        const QJsonValue value = it.value();

        if (value.isObject()) {// 如果值是对象，递归调用此函数
            resultMap[key] = recursiveReadJsonObject(value.toObject());
        }
        else if (value.isArray()){ // 如果值是数组，递归处理数组中的每个元素
            QVariantList variantList;
            const QJsonArray jsonArray = value.toArray();
            for (const auto &arrayValue : jsonArray) {
                if (arrayValue.isObject()) {
                    variantList.append(recursiveReadJsonObject(arrayValue.toObject()));
                } else if(arrayValue.isArray()){
                    variantList.append(recursiveReadJsonArray(arrayValue.toArray()));
                }
                else{
                    variantList.append(arrayValue.toVariant());
                }
            }
            resultMap[key] = variantList;
        }
        else
        {
            // 如果值不是对象也不是数组，直接转换为 QVariant
            resultMap[key] = value.toVariant();
        }
    }
    return resultMap;
}
QVariantList FileOperator::recursiveReadJsonArray(const QJsonArray &jsonArray){
    QVariantList variantList;
    for(const auto &arrayValue : jsonArray){//遍历一个json数组中的所有对象或嵌套数组
        if (arrayValue.isObject()) {
            variantList.append(recursiveReadJsonObject(arrayValue.toObject()));
        }
        else if(arrayValue.isArray()) {
            variantList.append(recursiveReadJsonArray(arrayValue.toArray()));
        }
        else
        {
            variantList.append(arrayValue.toVariant());
        }
    }
    return variantList;
}

QVariantMap FileOperator::parseJsonObjectFile(const QString path){
    QByteArray jsonData = readFile(path);
    return parseJsonObject(jsonData);
}

QVariantMap FileOperator::parseJsonObject(const QByteArray &jsonData){
    if (jsonData.isEmpty()) {
        qDebug() << "Failed to read Jsonfile content.";
        return QVariantMap();
    }

    QJsonParseError jsonError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &jsonError);

    if (jsonError.error != QJsonParseError::NoError) {
        qDebug() << "############## JSON ERROR ##############";
        qDebug() << "JSON parsing error";
        qDebug() << "ERROR INFO : " << jsonError.errorString();
        qDebug() << "########################";
        return QVariantMap();
    }

    if (jsonDoc.isObject()) {
        QJsonObject jsonObject = jsonDoc.object();
        return recursiveReadJsonObject(jsonObject);
    }
    else
    {
        qDebug() << "############## JSON ERROR ##############";
        qDebug() << "ERROR INFO : Document is not an object";
        qDebug() << "########################################";
        return QVariantMap();
    }
}

QVariantList FileOperator::parseJsonArrayFile(const QString path){
    QByteArray jsonData = readFile(path);
    return parseJsonArray(jsonData);
}
QVariantList FileOperator::parseJsonArray(const QByteArray &jsonData){
    if (jsonData.isEmpty()) {
        qDebug() << "Failed to read Jsonfile content.";
        return QVariantList();
    }

    QJsonParseError jsonError;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &jsonError);

    if (jsonError.error != QJsonParseError::NoError) {
        qDebug() << "############## JSON ERROR ##############";
        qDebug() << "JSON parsing error";
        qDebug() << "ERROR INFO : " << jsonError.errorString();
        qDebug() << "########################";
        return QVariantList();
    }

    if(jsonDoc.isArray()){
        QJsonArray jsonArray =jsonDoc.array();
        return recursiveReadJsonArray(jsonArray);
    }
    else
    {
        qDebug() << "############## JSON ERROR ##############";
        qDebug() << "ERROR INFO : Document is not an object";
        qDebug() << "########################################";
        return QVariantList();
    }
}

bool FileOperator::writeJsonFile(const QVariantMap &map, QString path) {
    // 创建 QJsonObject 并递归填充数据
    QJsonObject jsonObject = recursiveWriteJsonObject(map);

    // 创建 QJsonDocument 并将其转换为 JSON 格式的 QByteArray
    QJsonDocument jsonDoc(jsonObject);
    QByteArray jsonData = jsonDoc.toJson(QJsonDocument::Indented);

    // 写入文件
    if (!createDir_if(path)) {
        qDebug() << "无法创建目录:" << QDir::toNativeSeparators(path);
        return false;
    }
    return writeFile(path,jsonData);
}
bool FileOperator::writeJsonFile(const QVariantList &list,QString path){
    QJsonArray jsonArray=recursiveWriteJsonArray(list);
    QJsonDocument jsonDoc(jsonArray);
    QByteArray jsonData = jsonDoc.toJson(QJsonDocument::Indented);
    // 写入文件
    if (!createDir_if(path)) {
        qDebug() << "无法创建目录:" << QDir::toNativeSeparators(path);
            return false;
    }
    return writeFile(path,jsonData);
}

QJsonObject FileOperator::recursiveWriteJsonObject(const QVariantMap &map) {
    QJsonObject jsonObject;
    for (auto it=map.begin();it!=map.end();it++) {
        const QString key = it.key();
        const QVariant value = it.value();

        QJsonValue jsonValue;
        switch (value.type()) {
            //对象构建 QJsonObject
            case QVariant::Map:
            {
                const QVariantMap childMap = value.toMap();
                jsonValue=recursiveWriteJsonObject(childMap);
                break;
            }
            //数组构建 QJsonArray
            case QVariant::List:
            {
              const QVariantList variantList = value.toList();
                QJsonArray jsonArray;
                for (const QVariant &listItem : variantList) {
                    jsonArray.append(recursiveWriteJsonValue(listItem));
                }
                jsonValue = jsonArray;
                break;
            }
            default:
                // 对于其他类型，直接转换为 QJsonValue
                jsonValue = QJsonValue::fromVariant(value);
        }

        // 将键值对添加到 QJsonObject 中
        jsonObject.insert(key, jsonValue);
    }
    return jsonObject;
}

QJsonArray FileOperator::recursiveWriteJsonArray(const QVariantList &list){
    QJsonArray jsonArray;
    for(auto it=list.begin();it!=list.end();it++){
        jsonArray.append(recursiveWriteJsonValue(*it));
    }
    return jsonArray;
}

QJsonValue FileOperator::recursiveWriteJsonValue(const QVariant &value) {
    QJsonValue jsonValue;
    switch (value.type()) {
        //对象构建 QJsonObject
        case QVariant::Map: {
            const QVariantMap map = value.toMap();
            jsonValue = recursiveWriteJsonObject(map);
            break;
        }
        //数组构建 QJsonArray
        case QVariant::List: {
            const QVariantList list = value.toList();
            QJsonArray jsonArray;
            for (const QVariant &listItem : list) {
                jsonArray.append(recursiveWriteJsonValue(listItem));
            }
            jsonValue = jsonArray;
            break;
        }
        default:
            jsonValue = QJsonValue::fromVariant(value);
    }
    return jsonValue;
}
QString FileOperator::formatMessageTime(qint64 messageMilliseconds) {
    if(messageMilliseconds==0)
        return "";
    QDateTime currentTime = QDateTime::currentDateTime();
    QDateTime eventTime = QDateTime::fromMSecsSinceEpoch(messageMilliseconds);
    // 计算时间差
    qint64 secondsDiff = eventTime.secsTo(currentTime);
    qint64 daysDiff = currentTime.daysTo(eventTime);
    if (secondsDiff >= 0 &&secondsDiff < 24*60*60)
    {
        // 当天内，显示时和分
        return eventTime.toString("HH:mm");
    }
    else if(secondsDiff>=24*60*60&& secondsDiff<2*24*60*60){
        return eventTime.toString("昨天 HH:mm");;
    }
    else if (daysDiff > 0 && daysDiff <= 6)
    {
        // 一周内，显示星期几
        return eventTime.toString("dddd");
    }
    else if (daysDiff > 6 && daysDiff <= 29 + (currentTime.date().dayOfWeek() - 1))
    {
        // 一个月内（假设一个月最多30天，这里需要更精确的计算）
        return eventTime.toString("dd 天前");
    }
    else if (daysDiff > 0 && daysDiff <= 365)
    {
        // 一年内，显示几月几日
        return eventTime.toString("MM/dd");
    }
    else
    {
        // 超过一年，显示几年几月几日
        return eventTime.toString("yyyy/MM/dd");
    }
}
QMap<QString, QString> FileOperator::getQueryParamsFromUrl(const QString &url,const QString &delimiter) {
    //获取?所在的位置
    QMap<QString, QString> map;
    int start=url.indexOf('?')+1;
    if(start!=-1){
        int mid;
        int end;
        do{
            mid=url.indexOf('=',start);
            end=url.indexOf(delimiter,mid);
            map.insert(url.mid(start,mid-start),url.mid(mid+1,end-mid-1));
            start=end+delimiter.length();
        }while(end!=-1);
    }
    return map;
}

QMap<QString, QString> FileOperator::getQueryParamsFromUrl(const QString &url) {
    return getQueryParamsFromUrl(QUrl(url));
}
QMap<QString, QString> FileOperator::getQueryParamsFromUrl(const QUrl &url) { //只能处理&分隔符
    QUrlQuery query(url.query());
    QMap<QString, QString> queryItems;
    if (!query.isEmpty()) {
        const QList<QPair<QString, QString>> items = query.queryItems();
        for (const auto &item : items) {
                queryItems.insert(item.first, item.second);
        }
    }
    return queryItems;
}
